package com.hzjq.fxlib.ui

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.view.KeyEvent
import android.view.WindowManager
import android.widget.TextView
import com.hzjq.core.Blast
import com.hzjq.core.bean.ChargeProgressEntity
import com.hzjq.core.bean.ErrorCapEntity
import com.hzjq.core.bean.ErrorReadCapEntity
import com.hzjq.core.bean.ErrorResult
import com.hzjq.core.callback.Callback
import com.hzjq.core.callback.ProgressCallback
import com.hzjq.core.event.PioUnEnableEvent
import com.hzjq.fxlib.R
import com.hzjq.fxlib.event.LogEvent
import com.hzjq.fxlib.presenter.*
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BasePopupView
import com.lxj.xpopup.interfaces.OnConfirmListener
import com.wxl.common.base.AbsActivity
import com.wxl.common.util.Toll
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_charge_layout.*
import kotlinx.android.synthetic.main.activity_register_cap_layout.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.*
import kotlin.collections.HashMap


class ChargeActivity : AbsActivity() {

    companion object {
        fun start(context: Context, caps: ArrayList<ErrorCapEntity>, maxDelay:Long) {
            val intent = Intent(context, ChargeActivity::class.java)
            intent.putExtra("caps", caps)
            intent.putExtra("maxDelay",maxDelay)
            context.startActivity(intent)
        }
    }

    private var maxDelay = 0L
    private val caps = arrayListOf<ErrorCapEntity>()
    private val registerResultCaps = arrayListOf<ErrorCapEntity>()
    private val errorCaps = HashMap<Int,ErrorCapEntity>()
    private val errorCapCounts = HashMap<Int,Int>()
    private val errorCapKeys = arrayListOf<Int>()
    private var mElectric = 0f
    private var isChargeEnd = false
    private var isStartCharge = false
    private var presenters = arrayListOf<AbsViewPresenter>()
    private var position = 0
    private var disposable: Disposable? = null
    private var warnPopupView : BasePopupView? = null

    override fun getCreateContentViewId(): Int {
        return R.layout.activity_charge_layout
    }

    override fun onCreateViewChanged() {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        maxDelay = intent.getLongExtra("maxDelay",0)
        caps.clear()
        caps.addAll(intent.getSerializableExtra("caps") as ArrayList<ErrorCapEntity>)
        registerResultCaps.clear()

        findViewById<TextView>(R.id.titleTextView).textSize = 24f

        presenters.add(ChargeProgressPresenter(chargeContainerLayout))
        presenters.add(ChargeErrorPresenter(chargeContainerLayout))
        presenters.add(ChargeFinishPresenter(chargeContainerLayout))
        presenters[position].show()

        cancelCharge()
        chargeCap()
        onToBlast()
    }

    private fun onToBlast() {
        chargeToBlast.setOnClickListener {
            chargeToBlast.isEnabled = false
            chargeToBlast.isClickable = false
            BlastActivity.start(this,maxDelay,caps)
            finish()
        }
    }

    @Synchronized
    private fun chargeCap() {
        if(isStartCharge){
           return
        }
        isStartCharge  = true
        EventBus.getDefault().post(LogEvent("开始充电"))
        Blast.getInstance().charge()
            .onCharge(object : ProgressCallback<ChargeProgressEntity> {
                override fun onError(errorCode: ErrorResult) {
                    presenters[0].hide()
                    position = 1
                    presenters[position].show()
                    (presenters[position] as ChargeErrorPresenter).showAction("充电失败")
                }

                override fun onProgressChanged(progress: Int, total: Int, action: String) {
                    presenters[position].notifyProgressBar(action,progress)
                }

                override fun onResult(t: ChargeProgressEntity) {
                    ("电压:"+t.mVoltage.toString() + "V").also { chargeCapDy.text = it }
                    ("电流:"+t.mElectric.toString() + "mA").also { chargeCapDl.text = it }
                    this@ChargeActivity.mElectric = t.mElectric
                    if (t.code == 0) {
                        if (t.isEnd) {
                            isStartCharge = false
                            isChargeEnd = true
                            EventBus.getDefault().post(LogEvent("充电完成"))
                            convertOkCap()
                        }
                    }
                }

                override fun onRetryCountChanged(retryCount: Int, action: String) {

                }

            }, Consumer {
                if(it.caps[it.caps.size -1].isScanEnd) {
                    position = 1
                    presenters[position].show()
                    convertErrorCap(it)
                }
            })
    }


    @SuppressLint("CheckResult")
    private fun convertErrorCap(e: ErrorReadCapEntity){
        disposable?.dispose()
        disposable=  Observable.create<Boolean> {
            if(!registerResultCaps.containsAll(e.errors)) {
                registerResultCaps.clear()
                errorCapCounts.clear()
                errorCapKeys.clear()
                errorCaps.clear()
                val temp = arrayListOf<String>()
                e.errors.forEach {
                    if(!temp.contains(it.cap!!.uid)) {
                        registerResultCaps.add(it)
                        temp.add(it.cap!!.uid)
                        if (errorCapCounts.containsKey(it.errorCode)) {
                            errorCapCounts[it.errorCode] = errorCapCounts[it.errorCode]!! + 1
                        } else {
                            errorCapCounts[it.errorCode] = 1
                            errorCapKeys.add(it.errorCode)
                        }
                        errorCaps[it.errorCode] = it
                    }
                }
            }

            it.onNext(e.caps[e.caps.size -1].isScanEnd)
        }.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                showCaps(it)
            }
    }

    private fun showCaps(isEnd:Boolean) {
        presenters[0].hide()
        val size = errorCapKeys.size
        val buffer = StringBuffer()
        buffer.append("充电错误\n")
        for (i in 0 until size){
            if(i < errorCapKeys.size){
                val key = errorCapKeys[i]
                buffer.append(errorCaps[key]!!.error)
                    .append("  ")
                    .append(errorCapCounts[key])
                    .append("  发雷管")
            }
        }

        if(isEnd && registerResultCaps.isNotEmpty()){
            buffer.append("\n\n").append("请按F1查看详情。")
            (presenters[position] as ChargeErrorPresenter).isScanEnd(true,registerResultCaps)
        }

        (presenters[position] as ChargeErrorPresenter).showAction(buffer.toString())
    }


    private fun convertOkCap() {
        presenters[0].hide()
        registerResultCaps.clear()
        registerResultCaps.addAll(caps)
        position = 2
        (presenters[2] as ChargeFinishPresenter).setClickCallback(Runnable {
            chargeToBlast.performClick()
        })
        presenters[position].show()
    }



    private fun cancelCharge() {
        chargeCancel.setOnClickListener {
            if (warnPopupView != null && warnPopupView!!.isShow) {
                return@setOnClickListener
            }
            warnPopupView =   XPopup.Builder(this)
                .dismissOnTouchOutside(false)
                .dismissOnBackPressed(false)
                .asConfirm("警告", "雷管已充入高压，请按相关规定进行执行！",
                    OnConfirmListener {
                        turnVoltage()
                    }).show()
        }
    }


    private fun turnVoltage() {
        val show = XPopup.Builder(this)
            .hasShadowBg(false)
            .asLoading("正在退出...")
            .show()
        Blast.getInstance().charge()
            .onCloseElectric(object : Callback<Boolean> {
                override fun onError(errorCode: ErrorResult) {
                    show.dismiss()
                    Toll.toll("退出失败")
                }

                override fun onResult(t: Boolean) {
                    show.dismiss()
                    if (t) {
                        Blast.getInstance().charge().cancel()
                        finish()
                    } else {
                        Toll.toll("退出失败")
                    }
                }

                override fun onRetryCountChanged(
                    retryCount: Int,
                    action: String
                ) {

                }

            })
    }




    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onPioUnEnableEvent(e: PioUnEnableEvent){
        showPioUnEnablePop(this)
    }


    override fun getPageTitle(): String {
        return "雷管充电"
    }

    override fun onBackClick(): Boolean {
        chargeCancel.performClick()
        return false
    }

    override fun onBackPressed() {
        chargeCancel.performClick()
    }

    override fun onDestroy() {
        super.onDestroy()
        presenters[0].hide()
        disposable?.dispose()
        Blast.getInstance().charge().cancel()
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if(keyCode == KeyEvent.KEYCODE_BACK){
            chargeCancel.performClick()
            return true
        }
        return presenters[position].onKeyDown(keyCode, event)
    }
}